package mammuthus.web.action

import java.util
import javax.servlet.http.HttpServletRequest
import mammuthus.web.bean.{TaskDesc, Task, SlaveBean}
import mammuthus.web.service.SlaveService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.{ResponseBody, RequestParam, RequestMapping}

import scala.collection.JavaConversions._
import net.liftweb.{json => SJSon}
import net.liftweb.json.NoTypeHints
import org.slf4j.LoggerFactory

/**
 * Created by fengbingjian on 15/5/3 13:12.
 */
@Controller()
@RequestMapping(Array("app"))
class AppAction extends ActionHelperTrait with HadoopAction with HbaseAction with SparkNotebookAction {
  val logger = LoggerFactory.getLogger(classOf[AppAction])
  @Autowired
  val slaveService: SlaveService = null

  //val app:util.List[AppInfoBean] = List(new AppInfoBean("zookeeper", "3.4.6",null))

  @RequestMapping(Array("appIndex.html"))
  def index(req: HttpServletRequest) = {

    req.setAttribute("app", slaveService.getAppStore)
    req.setAttribute("page", "installManager")

    "appIndex"
  }

  @RequestMapping(Array("appInstalled.html"))
  def installed(req: HttpServletRequest) = {


    req.setAttribute("app", slaveService.appList())
    req.setAttribute("page", "appManager")


    "appInstalled"
  }

  @RequestMapping(Array("appInstalledDetail.html"))
  def installedDetail(req: HttpServletRequest,
                      @RequestParam("appName") appName: String,
                      @RequestParam("version") version: String) = {
    val params = putToReqAttribute(req)
    req.setAttribute("app", params.getOrElse("app", appName))
    req.setAttribute("appName", appName)
    req.setAttribute("version", version)
    req.setAttribute("slave", slaveService.appSlave(appName))
    req.setAttribute("page", "appManager")

    "appInstalledDetail"
  }

  @RequestMapping(Array("appInstallSelectSlave.html"))
  def appInstallSelectSlave(req: HttpServletRequest,
                            @RequestParam("app") app: String,
                            @RequestParam("appName") appName: String,
                            @RequestParam("version") version: String,
                            @RequestParam(value = "filter", defaultValue = "") filter: String,
                            @RequestParam(value = "step", defaultValue = "") step: String,
                            @RequestParam(value = "slave", defaultValue = "") slave: Array[String]
                             ) = {

    val temp = formatIP(slaveService.getSlave()).filterNot(f => f.docker.enable)

    val slaves: util.List[SlaveBean] = if (!filter.isEmpty)
      temp.filter {
        f =>
          filter.r.findFirstIn(f.getHostName) match {
            case Some(i) => true
            case None => false
          }
      }
    else temp
    req.setAttribute("iterKVs", new java.util.HashMap[String, String]())

    hadoopConfigure(req, app, step, slave)
    hbaseConfigure(req, app, step, slave)
    sparkNotebookConfigure(req, app, step, slave)
    normalConfigure(req, app, step, slave)

    val params = putToReqAttribute(req)

    req.setAttribute("slave", slaves)
    req.setAttribute("app", app)
    req.setAttribute("version", version)
    req.setAttribute("page", "installManager")
    req.setAttribute("title", "正在安装")

    val nextStep = if (step == "finish") params.getOrElse("submitPage", "/app/appDeploy.html") else params.getOrElse("submitPage", "/app/appInstallSelectSlave.html")
    req.setAttribute("nextStep", nextStep)

    if (step == "finish") "appInstallSelectSlaveMakeSure" else "appInstallSelectSlave"
  }


  def normalConfigure(req: HttpServletRequest, app: String, step: String, slave: Array[String]): Unit = {
    if (req.getAttribute("configureType") != null) return
    val stepName = if (step.isEmpty) {
      req.setAttribute("step", "finish")
      "zookeeper安装节点选取"
    } else {
      val iterKVs = new util.HashMap[String, String]()
      iterKVs.put("slave", slave.mkString(","))
      req.setAttribute("iterKVs", iterKVs)
    }
    req.setAttribute("stepName", stepName)
  }


  @RequestMapping(Array("appInstall.html"))
  def appInstall(req: HttpServletRequest,
                 @RequestParam("slave") slave: Array[String],
                 @RequestParam("app") app: String,
                 @RequestParam("appName") appName: String,
                 @RequestParam("version") version: String) = {


    req.setAttribute("slave", slave.mkString(","))
    req.setAttribute("app", app)
    req.setAttribute("version", version)
    req.setAttribute("appName", appName)
    putToReqAttribute(req)
    "appInstallDetail"

  }

  @RequestMapping(Array("appDeploy.html"))
  def appInstall(req: HttpServletRequest) = {

    val params = putToReqAttribute(req)
    val urlParams = encodeFromMapToUrlQuery(req.getParameterMap)

    val res = slaveService.deploy(params)
    nav2(req, params, res,
      prePath = (s"#", "-"),
      nextPath = (s"/app/appConfig.html?${urlParams}", "生成配置文件")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("appConfig.html"))
  def appConfig(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.config(params, "-").toList
    val appName = params.getOrElse("appName", "-")
    val appType = params.getOrElse("app", "-")
    val nextPath = if (Set("hadoop", "hbase").contains(appType)) {
      (s"/app/hadoop.html?appName=${appName}", "管理应用")
    } else (s"/app/appInstalled.html", "查看已安装应用")
    nav(req, res,
      nextPath = nextPath
    )
    "multiShellCommandExecuteResult"
  }

  @RequestMapping(Array("appInstallDeployFile.html"))
  @ResponseBody
  def appInstallDeployFile(req: HttpServletRequest,
                           @RequestParam("slave") slave: String,
                           @RequestParam("app") app: String,
                           @RequestParam("appName") appName: String,
                           @RequestParam("version") version: String) = {

    slaveService.installDeployFile(app, appName, version, slave, "", "-")

  }

  @RequestMapping(Array("appInstallDeployConfig.html"))
  @ResponseBody
  def appInstallDeployConfig(req: HttpServletRequest,
                             @RequestParam("slave") slave: String,
                             @RequestParam("app") app: String,
                             @RequestParam("appName") appName: String,
                             @RequestParam("version") version: String) = {
    var params = putToReqAttribute(req)
    List("slave", "appName", "version").foreach {
      f =>
        params = params - f
    }
    slaveService.installDeployConfig(app, appName, version, slave, "", "-", params)
  }

  @RequestMapping(Array("shellCommandExecuteDetail.html"))
  def shellCommandExecuteDetail(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val task = Task(TaskDesc(params("taskId"), params("hostName")), "")
    implicit val formats = SJSon.Serialization.formats(NoTypeHints)
    val res = slaveService.getTaskInfoUntilAllFinish(slaveService.masterUrl, SJSon.Serialization.write(List(task)), 10)
    req.setAttribute("tasks", toJava2(res))
    "shellCommandExecuteDetail"
  }
}
